package org.orz.story.works.biz.clubhouse.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.orz.cloud.common.enums.AliveFlagEnum;
import org.orz.story.works.biz.clubhouse.model.dto.DownloadNbaScheduleDTO;
import org.orz.story.works.biz.clubhouse.model.resp.ListNbaScheduleResp;
import org.orz.story.works.biz.clubhouse.persistence.entities.WorksNbaSchedule;
import org.orz.story.works.biz.clubhouse.persistence.mappers.WorksNbaScheduleMapper;
import org.orz.story.works.biz.clubhouse.service.NbaScheduleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class NbaScheduleServiceImpl implements NbaScheduleService {

    @Autowired
    private WorksNbaScheduleMapper worksNbaScheduleMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void downloadNbaScheduleJob() {
        String dataStr = HttpUtil.get("http://apis.juhe.cn/fapig/nba/query?key=84c841e5346a6ab8cd26fc374e8cac05");
        if (StrUtil.isBlank(dataStr)) {
            log.info("dataStr is blank: {}", dataStr);
            return;
        }
        JSONObject jsonObject = JSON.parseObject(dataStr);
        if (!"0".equals(jsonObject.getString("error_code")) || jsonObject.get("result") == null) {
            log.info("data error: {}", dataStr);
            return;
        }
        JSONObject result = jsonObject.getJSONObject("result");
        if (result.get("matchs") == null) {
            log.info("there is no match to save recent days: {}", dataStr);
            return;
        }
        List<DownloadNbaScheduleDTO> matchs = JSON.parseArray(result.getString("matchs"), DownloadNbaScheduleDTO.class);
        // 删除从昨天开始保存的数据
        WorksNbaSchedule deleteParam = new WorksNbaSchedule();
        deleteParam.setAliveFlag(AliveFlagEnum.DELETED.getKey());
        deleteParam.setUpdateUser(0L);
        deleteParam.setUpdateDate(new Date());
        worksNbaScheduleMapper.update(deleteParam, new LambdaQueryWrapper<WorksNbaSchedule>()
                .ge(WorksNbaSchedule::getDate, DateUtil.beginOfDay(DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, -1)))
                .eq(WorksNbaSchedule::getAliveFlag, AliveFlagEnum.ALIVE.getKey()));

        //保存新的数据
        matchs.forEach(data -> {
            data.getList().forEach(match -> {
                WorksNbaSchedule nbaSchedule = new WorksNbaSchedule();
                nbaSchedule.setDate(data.getDate());
                nbaSchedule.setWeek(data.getWeek());
                nbaSchedule.setTimeStart(match.getTime_start());
                nbaSchedule.setStatus(match.getStatus());
                nbaSchedule.setStatusText(match.getStatus_text());
                nbaSchedule.setTeam1(match.getTeam1());
                nbaSchedule.setTeam2(match.getTeam2());
                nbaSchedule.setTeam1Score(match.getTeam1_score());
                nbaSchedule.setTeam2Score(match.getTeam2_score());
                nbaSchedule.setCreateUser(0L);
                nbaSchedule.setCreateDate(new Date());
                worksNbaScheduleMapper.insert(nbaSchedule);
            });
        });
    }

    @Override
    public List<ListNbaScheduleResp> listNbaSchedule() {
        LambdaQueryWrapper<WorksNbaSchedule> wrapper = new LambdaQueryWrapper<WorksNbaSchedule>()
                .eq(WorksNbaSchedule::getAliveFlag, AliveFlagEnum.ALIVE.getKey());
        wrapper.orderByDesc(WorksNbaSchedule::getDate, WorksNbaSchedule::getTimeStart, WorksNbaSchedule::getId);
        List<WorksNbaSchedule> worksNbaSchedules = worksNbaScheduleMapper.selectList(wrapper);
        if(CollUtil.isEmpty(worksNbaSchedules)){
            return Collections.emptyList();
        }

        List<ListNbaScheduleResp> resultList = new ArrayList<>();
        ListNbaScheduleResp result = new ListNbaScheduleResp();
        for (int i = 0; i < worksNbaSchedules.size(); i++) {
            int begin = i;
            WorksNbaSchedule item = worksNbaSchedules.get(i);
            do {
                if(i < worksNbaSchedules.size() - 1 && worksNbaSchedules.get(i + 1).getDate().getTime() == item.getDate().getTime()){
                    i++;
                } else {
                    break;
                }
            } while (true);
            result.setDate(DateUtil.format(item.getDate(), "yyyy-MM-dd"));
            result.setWeek(item.getWeek());
            List<ListNbaScheduleResp.Match> matchList = worksNbaSchedules.subList(begin, i+1).stream().map(match -> {
                ListNbaScheduleResp.Match matchData = new ListNbaScheduleResp.Match();
                matchData.setId(match.getId());
                matchData.setTimeStart(match.getTimeStart());
                matchData.setStatusText(match.getStatusText());
                matchData.setTeam1(match.getTeam1());
                matchData.setTeam2(match.getTeam2());
                matchData.setTeam1Score(match.getTeam1Score());
                matchData.setTeam2Score(match.getTeam2Score());
                return matchData;
            }).collect(Collectors.toList());
            result.setMatchList(matchList);
            resultList.add(JSON.parseObject(JSON.toJSONString(result), ListNbaScheduleResp.class));
        }
        return resultList;
    }
}
